<?php

/**
 * Clase para la manipulacion de contenido HTML
 * Impresion de textos con formatos y controles enlazados.
 * 
 * @author Rommel Meza (@cxrom)
 *
 */
class CHtml{

	/**
	 * Impresion de un texto con formato alfanumerico
	 * @var String
	 */
	const C_Format_Text 	= 'text';
	/**
	 * Impresion de un texto con formato numerico
	 * @var String
	 */
	const C_Format_Number 	= 'number';
	/**
	 * Impresion de un texto con formato de fecha
	 * @var String
	 */
	const C_Format_Date 	= 'date';
	/**
	 * Impresion de un texto con formato de tiempo
	 * @var String
	 */
	const C_Format_Time 	= 'time';
	
	/**
	* Impresion de un texto con formato de tiempo
	* @var String
	*/
	const C_Format_Currency = 'currency';
	
	/**
	 * Nombre del formulario activo.
	 * @var String
	 */
	public static $actual_form;
	/**
	 * Modelo del formulario activo en caso de tener uno.
	 * @var CBaseModel
	 */
	public static $actual_model;
	/**
	 * Indica si el formulario trabaja en modo de lista
	 * @var Bool
	 */
	public static $is_list;
	public static $count_list;
	
	private static $form_script;
	
	/**
	 * Imprime inicio de formulario.
	 * @param CBaseModel $model Modelo que administrara el formulario.
	 * @param String $name Nombre del fomulario defaul random().
	 * @param String $command Comando donde estara dirigido el formulario.
	 * @param Action $action Accion donde estara dirigido el formulario.
	 * @param Bool $autocomplete Indica si los campos recuerdan historial.
	 * @param Bool $islist Indica si se trabaja con lista
	 * @param Int $count Cantidad de elementos en caso de ser lista
	 */
	public static function OpenForm($model=null, $name=null, $command=null, $action=null, $autocomplete=false, $islist=false, $count=0){
		
		if($name==null){ $name='form_'.rand(); }
		if($command==null){ $command=App::$Request->_command; }
		if($action==null){ $action=App::$Request->_action; }
		if($autocomplete==false){ $autocomplete = "autocomplete=\"off\""; }
		
		self::$is_list = $islist;
		self::$count_list = $count;
		self::$actual_form = $name;
		self::$actual_model = $model;
		
		self::$form_script = "<script type='text/javascript'>\r";
		
		//Generacion de validacion del cliente
		$form = "<form id=\"$name\" name=\"$name\" method=\"post\" $autocomplete action=\"".App::$Response->makeUrl($command, $action)."\">\n";
		echo $form;
	}
	
	/**
	 * Funcion para cerrar formulario y escribir mascaras de captura de modelo y scripts de validacion.
	 */
	public static function CloseForm(){
		//En caso de ser lista guarda un valor con la cantidad de elementos a recuperar
		if(self::$is_list){
			echo "<input type='hidden' id='kn_form_list_count' name='kn_form_list_count' value='".self::$count_list."'/>";
		}
		
		echo "</form>\n";
		
		if(self::$actual_model){
			//Aplica mascaras de captura
			echo "<script type='text/javascript'>\r";
			foreach(get_object_vars(self::$actual_model) as $item => $opts){
				if(get_class($opts)=='CModelField'){
					
					$mask = $opts->inputmask;
					$length = $opts->length;
					
					if(self::$is_list){
						for($i=0;$i<=self::$count_list-1;$i++){
							$control = $opts->id_control."_i$i";
							self::printMask($mask, $control, $length);
						}
					}else{
						self::printMask($mask, $opts->id_control, $length);
					}
					
					
				}
			}
			echo "</script>\r";
		}
		
		self::$form_script .= "</script>\r";
		echo (self::$form_script);
		
		self::$form_script = null;
		self::$actual_model = null;
		self::$actual_form = null;
	}
	
	private static function printMask($mask, $control, $length){
		switch($mask){
			case CMaskTag::AlfaNumeric:
				//echo "$('#".$opts->id_control."').inputmask({ 'mask': '*', 'repeat': ".$opts->length.", 'greedy': false });\r";
				break;
			case CMaskTag::Date:
				echo "$('#".$control."').inputmask('d/m/y',{ 'placeholder': '_', 'clearIncomplete': true });\r";
				break;
			case CMaskTag::Number:
				echo "$('#".$control."').inputmask({ 'mask': '9', 'repeat': ".$length.", 'greedy': false });\r";
				break;
			case CMaskTag::Time:
				echo "$('#".$control."').inputmask('hh:mm',{ 'placeholder': '_', 'clearIncomplete': true });\r";
				break;
			case CMaskTag::Decimal:
				echo "$('#".$control."').inputmask('9',{ 'placeholder': '_' });\r";
				break;
		}
	}
	/**
	 * Imprime un texto codificando a CodeType definido
	 * @param String $message Mensaje a escribir
	 * @param  $format
	 * @param unknown_type $print
	 * @return string
	 */
	public static function Write($message, $format=CHtml::C_Format_Text, $print=true){
		if(($format==CHtml::C_Format_Number || $format==CHtml::C_Format_Currency) && 
		($message==null||$message=='')){
			$message='0';
		}
		$message = ($message==null)?'':$message;
		if($format==CHtml::C_Format_Date){
			$message = str_replace('-', '/', $message);
		}
		if($format==CHtml::C_Format_Currency){
			$message = self::formatMoney($message, true);
		}
		if($print){
			echo utf8_decode($message);
		}else{
			return utf8_decode($message);
		}
	}
	
	private function formatMoney($number, $fractional=false) {
		if ($fractional) {
			$number = sprintf('%.2f', $number);
		}
		while (true) {
			$replaced = preg_replace('/(-?\d+)(\d\d\d)/', '$1,$2', $number);
			if ($replaced != $number) {
				$number = $replaced;
			} else {
				break;
			}
		}
		return $number;
	}
	
	private static function getNameControl($name, $param){
		if(self::$is_list){
			if($param['index']>=0){
				return $name."_i".$param['index'];
			}
			return $name;
		}
		return $name;
	}

	/**
	 * Genera un Input TEXT en base a un campo de modelo.
	 * @param CModelField $field Campo que se desea parametrizar.
	 * @param Array $param Lista de parametros que se desean agregar al control.
	 * @param String $value Valor que se desea poner. Default toma el valor del modelo.
	 */
	public static function TextBox($field, $param, $value=null){
		$value  = "value='".self::Write((($value!=null) ? $value : $field->value), CHtml::C_Format_Text, false)."'";
		$id		= "id='".self::getNameControl($field->id_control, $param)."'";
		$name	= "name='".self::getNameControl($field->id_control, $param)."'";
		$add	= '';
		$maxlength = '';
		
		if($field->length){
			$maxlenght = "maxlength='".$field->length."'";	
		}
		
		foreach($param as $key => $val){
		if($key!='index'){
				$add .= "$key='$val' ";
			}
		}
		
		echo "<input type='text' $id $name $value $maxlenght $add/>";
	}

	/**
	 * Genera un Textarea en base a un campo de modelo
	 * @param CModelField $field Campo que se desea parametrizar.
	 * @param Array $param Lista de parametros que se desean agregar al control.
	 * @param String $value Valor que se desea poner. Default toma el valor del modelo.
	 */
	public static function TextArea($field, $param, $value=null){
		$value  = ($value) ? $value : $field->value;
		$id		= "id='".self::getNameControl($field->id_control, $param)."'";
		$name	= "name='".self::getNameControl($field->id_control, $param)."'";
		$add	= '';
		
		foreach($param as $key => $val){
		if($key!='index'){
				$add .= "$key='$val' ";
			}
		}
		
		echo "<textarea $id $name $add>".self::Write($value, CHtml::C_Format_Text, false)."</textarea>";
	}
	
	/**
	 * Genera un Input Hidden en base a un campo de modelo.
	 * @param CModelField $field Campo que se desea parametrizar.
	 * @param String $value Valor que se desea poner. Default toma el valor del modelo.
	 */
	public static function Hidden($field, $param, $value=null){
		$value  = "value='".(($value) ? $value : $field->value)."'";
		$id		= "id='".self::getNameControl($field->id_control, $param)."'";
		$name	= "name='".self::getNameControl($field->id_control, $param)."'";
		$add	= '';
		
		foreach($param as $key => $val){
		if($key!='index'){
				$add .= "$key='$val' ";
			}
		}
		
		echo "<input type='hidden' $id $name $value $add/>";
	}
	
	/**
	 * Genera un Combobox en base a un campo de modelo.
	 * @param Array $items Lista de elementos que contendra el combo.
	 * @param CModelField $field Campo que se desea parametrizar.
	 * @param String $action Accion del servidor en caso de requerir evento OnChange.
	 * @param String $div Div que actualizara el retorno de la peticion del servidor. 
	 * @param Array $param Lista de parametros que se desean agregar al control.
	 * @param Array $paramURL Lista de parametrosque se agregan al URL.
	 * @param Bool $script Indica si se integrara al script del formulario
	 */
	public static function ComboBox($items, $field, $action=null, $div=null, $param=null, $paramURL=null, $script=false){
		$id = $field->id_control;
		$nameControl = self::getNameControl($field->id_control, $param);
		$internal_script = "";
		if($action){
			$queryString = array();
			$queryString["idCombobox"] = $id;
			foreach($paramURL as $key => $val){
				$queryString[$key] = $val;
			}
			$url = CAjax::$JS->callUpdateDivWithForm(null, $action, null, null, $queryString, false, $div);
			$action = 'onchange="'.$url.'"';
		}
		
		$add	= '';
		foreach($param as $key => $val){
			if($key!='index'){
				$add .= "$key='$val' ";
			}
		}
		
		echo '<select name="'.$nameControl.'" id="'.$nameControl.'" '.$action.' '.$add.'>'."\n";
		echo '<option value="" selected>--></option>'."\n";
		foreach($items as $key => $val){
			if($field->value == $key || $paramURL['selectedValue'] == $key){
				
				if($script){
					$internal_script .= "<script type='text/javascript'>\r";
					$internal_script .= "$('#$nameControl').val($key); $('#$nameControl').trigger('change');\r";
					$internal_script .= "</script>";
				}else{
					self::$form_script .= "$('#$nameControl').val($key); $('#$nameControl').trigger('change');\r";
				}
			}
			echo "<option value=\"$key\">".self::Write($val, CHtml::C_Format_Text, false)."</option>\n";
		}
		echo "</select>\r";
		echo $internal_script;
	}
}